﻿using System;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Caching.Redis;
using NetCoreCacheIntroduce.Models;

namespace NetCoreCacheIntroduce.Controllers
{
    public class HomeController : Controller
    {
        private readonly IMemoryCache _cache;
        private readonly IDistributedCache _distributedCache;

        public HomeController(IMemoryCache cache,
            IDistributedCache distributedCache)
        {
            _cache = cache;
            _distributedCache = distributedCache;
        }

        public IActionResult Index()
        {
            return View();
        }

        public IActionResult About()
        {
            ViewData["Message"] = "Your application description page.";
            return View();
        }

        public IActionResult Cache()
        {
            DateTime cacheEntry;
            // Look for cache key.
            if (!_cache.TryGetValue("cacheEntry", out cacheEntry))
            {
                // Key not in cache, so get data.
                cacheEntry = DateTime.Now;
                // Set cache options.
                var cacheEntryOptions = new MemoryCacheEntryOptions()
                    // Keep in cache for this time, reset time if accessed.
                    .SetSlidingExpiration(TimeSpan.FromSeconds(3));
                // Save data in cache.
                _cache.Set("cacheEntry", cacheEntry, cacheEntryOptions);
            }
            return View("Cache", cacheEntry);
        }

        public IActionResult DistributedCache()
        {
            byte[] bytes = _distributedCache.Get("DistributedCache");
            string cacheEntry;

            // Look for cache key.
            if (bytes == null || !bytes.Any())
            {
                // Key not in cache, so get data.
                cacheEntry = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                // Set cache options.
                var distributedCacheEntryOptions = new DistributedCacheEntryOptions()
                    .SetSlidingExpiration(TimeSpan.FromSeconds(10));
                bytes = Encoding.UTF8.GetBytes(cacheEntry);
                // Save data in cache.
                _distributedCache.Set("DistributedCache", bytes, distributedCacheEntryOptions);
            }

            return View("DistributedCache", Encoding.UTF8.GetString(bytes));
        }

        public IActionResult Contact()
        {
            ViewData["Message"] = "Your contact page.";

            return View();
        }

        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
}
